package easypsync.ics;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class Event {
    public String getUid() {
		return uid;
	}

	public void setUid(String uid) {
		this.uid = uid;
	}

	public Date getDtstart() {
		return dtstart;
	}

	public void setDtstart(Date dtstart) {
		this.dtstart = dtstart;
	}

	public Date getDtend() {
		return dtend;
	}

	public void setDtend(Date dtend) {
		this.dtend = dtend;
	}

	public Date getDtstamp() {
		return dtstamp;
	}

	public void setDtstamp(Date dtstamp) {
		this.dtstamp = dtstamp;
	}

	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}
	
	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public List<String> getRest() {
		return rest;
	}

	public void setRest(List<String> rest) {
		this.rest = rest;
	}

	String uid;
    Date dtstart;
    Date dtend;
    Date dtstamp;
    String summary;
    String location;
    
    // This is to retain the non interpretable lines
    List<String> rest = new ArrayList<String>();

    static final SimpleDateFormat dfglobal = new SimpleDateFormat( "yyyyMMdd'T'HHmmss'Z'" );
    static final SimpleDateFormat dflocal = new SimpleDateFormat( "yyyyMMdd'T'HHmmss" );
    
    public Event() {
        this.uid = UUID.randomUUID().toString();
    }
    
    public Event(Date dtstart, Date dtend, String summary) {
        this.uid = UUID.randomUUID().toString();
        this.dtstart = dtstart;
        this.dtend = dtend;
        this.summary = summary;
    }
    
    public void write(OutputStream out) throws IOException {
        BufferedWriter bf = new BufferedWriter(new OutputStreamWriter(out), 8192);
        bf.write("BEGIN:VEVENT\r\n");
        bf.write("UID:");bf.write(uid);bf.write("\r\n");
        // NOTE: This is specific to my Mozilla calendar which is set to german time!!!
        bf.write("DTSTART;TZID=Europe/Berlin:");bf.write(dflocal.format(dtstart));bf.write("\r\n");
        bf.write("DTEND;TZID=Europe/Berlin:");bf.write(dflocal.format(dtend));bf.write("\r\n");
        bf.write("DTSTAMP:");bf.write(dfglobal.format(new Date()));bf.write("\r\n");
        bf.write("SUMMARY:");bf.write(summary);bf.write("\r\n");
        bf.write("LOCATION:");bf.write(location);bf.write("\r\n");
        for (String extraline : rest) {
            bf.write(extraline);bf.write("\r\n");
        }
        bf.write("END:VEVENT");bf.write("\r\n");
        
        bf.flush();
    }

    public void read(InputStream in) throws IOException, ParseException {        
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        read(br);
    }

    public void read(BufferedReader br) throws IOException, ParseException {
        String line;
        while ((line = br.readLine()) != null) {
            if (line.contains("END:VEVENT")) {
                break;
            }
            else if (line.startsWith("UID:"))
                uid = line.substring(4);
            else if (line.startsWith("DTSTART:"))
                dtstart = dflocal.parse(line.substring(27)); // Consider the time zone length
            else if (line.startsWith("DTEND:"))
                dtend = dflocal.parse(line.substring(25));
            else if (line.startsWith("DTSTAMP:"))
                dtstamp = dfglobal.parse(line.substring(8));
            else if (line.startsWith("SUMMARY:"))
                summary = line.substring(8);
            else if (line.startsWith("LOCATION:"))
                summary = line.substring(9);
            else
                rest.add(line);
        }
    }
    
    public String toString() {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            write(baos);
            return baos.toString();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }
    
    // TEST //
    public static void main(String[] args) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
        Event e1 = new Event(new Date(), new Date(), "hkjhk");
        e1.rest.add("NOTKNOWN:anyvalue");
        
        try {
            e1.write(baos);
            byte[] b = baos.toByteArray();
            
            ByteArrayInputStream bais = new ByteArrayInputStream(b);
            
            Event eTest = new Event();
            eTest.read(bais);
            bais.close();
            baos.close();
            
            System.out.println(eTest);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}
